/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.XPath;
using DaveSexton.DocProject.Sandcastle.TopicManagement;

namespace DaveSexton.DocProject.Sandcastle.ContentManagement
{
	public sealed class XmlConceptualTopic : IXmlTopic
	{
		#region Public Properties
		public string Name
		{
			get
			{
				return topic.Name;
			}
		}

		public string XmlDocument
		{
			get
			{
				return uncommittedXml ?? xml;
			}
			set
			{
				if (string.Equals(xml, value, StringComparison.Ordinal))
					return;

				uncommittedXml = value;

				OnXmlDocumentChanged(EventArgs.Empty);
			}
		}

		public bool IsDirty
		{
			get
			{
				return uncommittedXml != null;
			}
		}
		#endregion

		#region Private / Protected
		private readonly Topic topic;
		private string xml, uncommittedXml;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="XmlConceptualTopic" /> class.
		/// </summary>
		public XmlConceptualTopic(Topic topic)
		{
			if (topic == null)
				throw new ArgumentNullException("topic");

			this.topic = topic;
		}
		#endregion

		#region Methods
		public void CommitChanges()
		{
			xml = uncommittedXml;
			uncommittedXml = null;
		}

		public void CancelChanges()
		{
			uncommittedXml = null;
		}
		#endregion

		#region Events
		private readonly object XmlDocumentChangedEventLock = new object();
		private EventHandler XmlDocumentChangedEvent;

		/// <summary>
		/// Event raised when the <see cref="XmlDocument"/> property value changes.
		/// </summary>
		public event EventHandler XmlDocumentChanged
		{
			add
			{
				lock (XmlDocumentChangedEventLock)
				{
					XmlDocumentChangedEvent += value;
				}
			}
			remove
			{
				lock (XmlDocumentChangedEventLock)
				{
					XmlDocumentChangedEvent -= value;
				}
			}
		}

		/// <summary>
		/// Raises the <see cref="XmlDocumentChanged" /> event.
		/// </summary>
		/// <param name="e"><see cref="EventArgs" /> object that provides the arguments for the event.</param>
		private void OnXmlDocumentChanged(EventArgs e)
		{
			EventHandler handler = null;

			lock (XmlDocumentChangedEventLock)
			{
				handler = XmlDocumentChangedEvent;
			}

			if (handler != null)
				handler(this, e);
		}
		#endregion

		#region IXmlTopic Members
		public bool CanCreateSection
		{
			get
			{
				return false;
			}
		}

		public void NotifySectionChanged(string section)
		{
			OnXmlDocumentChanged(EventArgs.Empty);
		}

		public System.Xml.XmlElement CreateSection(string section)
		{
			throw new NotSupportedException();
		}
		#endregion
	}
}
